package com.googlecode.sparda.commons.logging;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.googlecode.sparda.commons.util.Percentager;

/**
 * Class to log the percentage string formatted by a {@link Percentager}, every <i>x</i> step.
 * @author Fabio Grucci (<i>alias</i> <b>Phoenix</b>)
 *
 */
public class PercentagerLogger {
	/**
	 * The default logging {@link Level} for the percentage.
	 */
	private static final Level DEFAULT_PERCENTAGE_LOGGING_LEVEL = Level.INFO;
	/**
	 * The default percentage step to log. Default is every 10%
	 */
	private static final double DEFAULT_STEP = 0.1;
	/**
	 * The log {@link Level} used in log messages.
	 */
	private final Level logLevel;
	/**
	 * The {@link Logger} used to log the percentage messages.
	 */
	private final Logger logger;
	/**
	 * The {@link Percentager} used to build the percentage and where 
	 * get the percentage as a string.
	 */
	private final Percentager percentager;
	/**
	 * The step interval between to logging event.
	 */
	private final double loggingStep;
	/**
	 * The next percentage to reach first than raise another logging event.
	 */
	private double nextStep;
	/**
	 * Build a {@link PercentagerLogger} that log in the {@link Logger} at 
	 * the info {@link Level}.
	 * This constructor build a {@link PercentagerLogger}
	 * using a {@link Percentager}.
	 * @param logger The {@link Logger} used in the logging
	 * @param totalStepCount The number of step used in {@link Percentager} constructor
	 */
	public PercentagerLogger(Logger logger, int totalStepCount) {
		this(logger, totalStepCount, DEFAULT_STEP);
	}
	/**
	 * Build a {@link PercentagerLogger} that log in the {@link Logger} at 
	 * the info {@link Level}.
	 * @param logger The {@link Logger} used in the logging
	 * @param totalStepCount The number of step used in {@link Percentager} constructor
	 * @param loggingStep The number of step between to logging step
	 */
	public PercentagerLogger(Logger logger, int totalStepCount, double loggingStep) {
		this(logger, new Percentager(totalStepCount), loggingStep);
	}
	/**
	 * Build a {@link PercentagerLogger} that log in the {@link Logger} at 
	 * the info {@link Level}.
	 * @param logger The {@link Logger} used in the logging
	 * @param percentager The {@link Percentager} used calculate the percentage and build the string to log
	 * @param loggingStep The number of step between to logging step
	 */
	public PercentagerLogger(Logger logger, Percentager percentager, double loggingStep) {
		this(DEFAULT_PERCENTAGE_LOGGING_LEVEL, logger, percentager, loggingStep);
	}
	/**
	 * Build a {@link PercentagerLogger} that log in the {@link Logger} at 
	 * the info {@link Level}.
	 * @param logLevel The {@link Level} when logging
	 * @param logger The {@link Logger} used in the logging
	 * @param percentager The {@link Percentager} used calculate the percentage and build the string to log
	 * @param loggingStep The number of step between to logging step
	 */
	public PercentagerLogger(Level logLevel, Logger logger, Percentager percentager, double loggingStep) {
		this.logger = logger;
		this.percentager = percentager;
		this.loggingStep = loggingStep;
		this.nextStep = loggingStep;
		this.logLevel = logLevel;
		this.logger.log(logLevel, this.percentager.toString());
	}
	/**
	 * Method to call to signal another step of the processing, this method
	 * log in the logger if the next step value is reached.
	 * Semantic similar to the {@link Percentager#next()} method.
	 * @see Percentager#next()
	 */
	public void next() {
		double next = this.percentager.next();
		if(next >= this.nextStep) {
			this.nextStep = Math.min(100, this.nextStep + this.loggingStep);
			logger.log(logLevel, this.percentager.toString());
		}
	}
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Percentage Logger (logLevel=" + this.logLevel + ", loggingStep="+ this.loggingStep + ")";
	}
	
}
